package com.tanhua.admin.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tanhua.admin.mapper.AnalysisMapper;
import com.tanhua.admin.mapper.LogMapper;
import com.tanhua.admin.utils.ComputeUtil;
import com.tanhua.model.domain.Analysis;
import com.tanhua.model.vo.AnalysisSummaryVo;
import com.tanhua.model.vo.AnalysisUsersVo;
import com.tanhua.model.vo.DataPointVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AnalysisService {

    @Autowired
    private LogMapper logMapper;

    @Autowired
    private AnalysisMapper analysisMapper;

    /**
     * 定时统计tb_log表中的数据，保存或者更新tb_analysis表
     *  1、查询tb_log表（注册用户数，登录用户数，活跃用户数，次日留存）
     *  2、构造Analysis对象
     *  3、保存或者更新
     */
    public void analysis() throws ParseException {
        //1、定义查询的日期
        String todayStr = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String yesdayStr = DateUtil.yesterday().toString("yyyy-MM-dd");
        //2、统计数据-注册数量
        Integer regCount = logMapper.queryByTypeAndLogTime("0102", todayStr);
        //3、统计数据-登录数量
        Integer loginCount = logMapper.queryByTypeAndLogTime("0101", todayStr);
        //4、统计数据-活跃数量
        Integer activeCount = logMapper.queryByLogTime(todayStr);
        //5、统计数据-次日留存
        Integer numRetention1d = logMapper.queryNumRetention1d(todayStr, yesdayStr);
        //6、构造Analysis对象
        //7、根据日期查询数据
        QueryWrapper<Analysis> qw = new QueryWrapper<Analysis>();
        qw.eq("record_date",new SimpleDateFormat("yyyy-MM-dd").parse(todayStr));
        Analysis analysis = analysisMapper.selectOne(qw);
        //8、如果存在，更新，如果不存在保存
        if(analysis != null) {
            analysis.setNumRegistered(regCount);
            analysis.setNumLogin(loginCount);
            analysis.setNumActive(activeCount);
            analysis.setNumRetention1d(numRetention1d);
            analysisMapper.updateById(analysis);
        }else {
            analysis = new Analysis();
            analysis.setNumRegistered(regCount);
            analysis.setNumLogin(loginCount);
            analysis.setNumActive(activeCount);
            analysis.setNumRetention1d(numRetention1d);
            analysis.setRecordDate(new SimpleDateFormat("yyyy-MM-dd").parse(todayStr));
            analysis.setCreated(new Date());
            analysis.setUpdated(new Date());
            analysisMapper.insert(analysis);
        }
    }




    /**
     * 新增、活跃用户、次日留存率
     * @param sd 开始时间
     * @param ed 结束时间
     * @param type 101 新增 102 活跃用户 103 次日留存率
     * @return
     */
    public AnalysisUsersVo queryAnalysisUsersVo(Long sd, Long ed, Integer type) {
        AnalysisUsersVo vo =new AnalysisUsersVo();
        //获取开始时间(时间毫秒值转日期)
        DateTime startDate = DateUtil.date(sd);
        //获取结束时间(时间毫秒值转日期)
        DateTime endDate = DateUtil.date(ed);

        List<DataPointVo> thisyear = this.queryDataPointVos(startDate, endDate, type);
        //查询今年活跃用户数量 日期
        vo.setThisYear(thisyear);

        //定义去年开始时间
        DateTime lastStart = DateUtil.offset(startDate, DateField.YEAR, -1);
        //定义去年结束时间
        DateTime lastEnd = DateUtil.offset(endDate, DateField.YEAR, -1);
        List<DataPointVo> lastyear = this.queryDataPointVos(lastStart, lastEnd, type);
        //查询去年活跃用户数量 日期
        vo.setLastYear(lastyear);
        return vo;
    }

    /**
     * 获取当年的新增,活跃用户,次日留存的数据和日期
     * @param startDate 开始时间
     * @param endDate  结束时间
     * @param type  类型 //101 新增 102 活跃用户 103 次日留存率
     * @return
     */
    private List<DataPointVo> queryDataPointVos(DateTime startDate, DateTime endDate, Integer type) {
        //日期转字符串
        String startTime = startDate.toDateStr();
        //日期转字符串
        String endTime = endDate.toDateStr();

       //定义一个对象,用于保存类型对应要查询的字段名
        String column =null;
        switch (type) { //101 新增 102 活跃用户 103 次日留存率
            case 101:
                column = "num_registered";
                break;
            case 102:
                column = "num_active";
                break;
            case 103:
                column = "num_retention1d";
                break;
            default:
                column = "num_active";
                break;
        }

        //查询今年新增用户数量 日期
        QueryWrapper<Analysis> lqw =new QueryWrapper<>();
        lqw.select("record_date , " + column + " as num_active")
                .ge("record_date", startDate)
                .le("record_date", endDate);
        List<Analysis> analysisList = analysisMapper.selectList(lqw);
        //遍历analysisList集合,将遍历出来的数据赋值给DataPointVo对象
        List<DataPointVo> collect = analysisList.stream()
                .map(item -> new DataPointVo(DateUtil.date(item.getRecordDate()).toDateStr(), item.getNumActive()))
                .collect(Collectors.toList());
        return collect;
    }

    /**
     * 获取累计用户数量(累加所有注册人数)
     * @return
     */
    public Integer querySumRegister() {
        Integer register = analysisMapper.querySumRegister();
        return register;
    }



    /**
     * 获取过去天数活跃用户数量
     * @param dateTime 今日日期
     * @param offset  过去的天数
     * @return
     */
    public Integer queryactiveUserCount(DateTime dateTime, int offset) {
        //日期转字符串
        String todaystr = DateUtil.formatDate(dateTime);
        //获取过去天数的日期
        Date newDates = DateUtil.offsetDay(dateTime, offset);
        //过去日期转字符串
        String pastDate = DateUtil.formatDate(newDates);
        //根据今日日期字符串和过去天数字符串,查找过去天数活跃用户数量
        Integer queryactiveUserCount = analysisMapper.queryactiveUserCount(pastDate,todaystr);
        return queryactiveUserCount;
    }

    /**
     * 当日新增用户数量(当天注册的人数)
     * @param todaystr
     * @return
     */
    public Integer queryNewUserCount(String todaystr) {
        Integer newUserCount = analysisMapper.queryNewUserCount(todaystr);
        return newUserCount;
    }

    /**
     * 当日登录次数
     * @param todaystr
     * @return
     */
    public Integer queryLoginCount(String todaystr) {
       Integer loginCount = analysisMapper.queryLoginCount(todaystr);
        return loginCount;
    }

    /**
     * 当日活跃用户数量
     * @param todaystr
     * @return
     */
    public Integer queryActiveUser(String todaystr) {
        Integer loginCount = analysisMapper.queryActiveUser(todaystr);
        return loginCount;
    }
}
